package com.sc.nft.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.sc.nft.dao.*;
import com.sc.nft.dto.UserHoldVO;
import com.sc.nft.entity.*;
import com.sc.nft.enums.IncomeHierarchyEnum;
import com.sc.nft.enums.IncomeTypeEnum;
import com.sc.nft.enums.WalletDetailTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.EquitySharePoolService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.sc.nft.service.EquityProfitRuleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 服务接口实现
 *
 * @author zxy
 * @since 2024-08-31 18:09:02
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class EquityProfitRuleServiceImpl implements EquityProfitRuleService {
    private final UserWalletDetailDao userWalletDetailDao;
    private final UserIncomeRecordDao userIncomeRecordDao;
    private final UserWalletDao userWalletDao;
    private final EquitySharePoolDao equitySharePoolDao;
    private final EquitySharePoolDetailDao detailDao;
    private final EquitySharePoolService equitySharePoolService;
    private final UserCollectionDao userCollectionDao;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void calculateEquityProfit(EquityProfitRule rule,List<EquitySharePool> list) {
        DateTime now = DateTime.now();
        if(detailDao.checkShareWithDate(rule.getId(), DateUtil.beginOfDay(now), DateUtil.endOfDay(now))){
            return;
        }
        EquitySharePool equitySharePool = null;
        for (EquitySharePool sharePool : list) {
            if(sharePool.getId().longValue()==rule.getSharePoolId().longValue()){
                equitySharePool=sharePool;
                break;
            }
        }
        Assert.notNull(equitySharePool,()->new GlobalRunTimeException("未找到分红池"));
        BigDecimal shareAmount = equitySharePool.getSumAmount().multiply(rule.getShareRatio()).setScale(2,RoundingMode.FLOOR);
        equitySharePoolService.subPool(rule, shareAmount);
        List<UserHoldVO> userHoldByCollectionId = userCollectionDao.getUserHoldByCollectionId(rule.getCollectionId());
        if(CollUtil.isEmpty(userHoldByCollectionId)){
            return;
        }
        Integer sumCount = userHoldByCollectionId.stream().map(UserHoldVO::getHoldCount).reduce(Integer::sum).get();
        BigDecimal oneCountAmount = shareAmount.divide(BigDecimal.valueOf(sumCount),8,RoundingMode.FLOOR);
        for (UserHoldVO userHoldVO : userHoldByCollectionId) {
            BigDecimal amount = oneCountAmount.multiply(BigDecimal.valueOf(userHoldVO.getHoldCount())).setScale(2, RoundingMode.FLOOR);
            if(NumberUtil.equals(amount,BigDecimal.ZERO)){
                continue;
            }
            addMoney(userHoldVO.getUserId(),rule.getId(),Long.parseLong(now.toString("yyyyMMdd")),null,amount,amount,BigDecimal.valueOf(userHoldVO.getHoldCount()),IncomeTypeEnum.PROPS_SHARE,IncomeHierarchyEnum.SPECIAL,
                    rule.getProfitName(), userHoldVO.getHoldCount().toString(),sumCount.toString());
        }

    }


    private void addMoney (Long userId,  Long sourceUserId, Long orderId, String
            orderNo, BigDecimal sumAmount, BigDecimal amount, BigDecimal ratio, IncomeTypeEnum
                                   incomeType, IncomeHierarchyEnum incomeHierarchy, String remark, String weightNum, String incomeNum){
        //收益幂等性校验
        UserIncomeRecord checkIncomeRecord = userIncomeRecordDao.checkRepeat(userId, orderId,sourceUserId, incomeType, incomeHierarchy);
        if (ObjectUtil.isNotNull(checkIncomeRecord) || NumberUtil.isLessOrEqual(amount, BigDecimal.ZERO)) {
            return;
        }
        //添加收益
        userWalletDao.addIncome(userId, amount);

        //添加记录/钱包明细
        UserIncomeRecord userIncomeRecord = new UserIncomeRecord();
        //金额
        userIncomeRecord.setAmount(amount);
        //用户
        userIncomeRecord.setUserId(userId);
        userIncomeRecord.setOrderId(orderId);
        //收益类型
        userIncomeRecord.setIncomeType(incomeType);
        userIncomeRecord.setIncomeTypeName(StrUtil.isNotBlank(remark)?remark:incomeType.getDescription());
        //收益层级
        userIncomeRecord.setIncomeHierarchy(incomeHierarchy);
        userIncomeRecord.setIncomeHierarchyName(incomeHierarchy.getDescription());
        //订单号
        userIncomeRecord.setOrderNo(orderNo);
        //订单金额
        userIncomeRecord.setIncomeCardinality(sumAmount);
        //奖励比例
        userIncomeRecord.setIncomeProportion(ratio.toPlainString());
        userIncomeRecord.setIncomeUserNum(incomeNum);
        userIncomeRecord.setWeightsNum(weightNum);
        //来源用户
        userIncomeRecord.setSourceUserId(sourceUserId);
        userIncomeRecord.insert();
        UserWallet wallet = userWalletDao.getByUserId(userId);
        //添加钱包明细
        UserWalletDetail userWalletDetail = new UserWalletDetail();
        userWalletDetail.setUserId(userId);
        userWalletDetail.setType(WalletDetailTypeEnum.INCOME);
        userWalletDetail.setAmount(amount);
        userWalletDetail.setCharge(BigDecimal.ZERO);
        userWalletDetail.setRealAmount(amount);
        userWalletDetail.setBeforeBalance(wallet.getBalance());
        userWalletDetail.setAfterBalance(wallet.getBalance().add(amount));
        userWalletDetail.setIsAdd(Boolean.TRUE);
        userWalletDetail.setRemark(remark);
        userWalletDetailDao.insert(userWalletDetail);
    }
}